// src/utils/template.ts
import fs from 'fs-extra';
import path from 'path';
import { logger } from './logger';

// 复制模板文件
export const copyTemplate = async (
  templateName: string, 
  targetDir: string, 
  variables: Record<string, any> = {}
): Promise<void> => {
  const templateDir = path.join(__dirname, '../../templates', templateName);
  
  // 检查模板是否存在
  if (!(await fs.pathExists(templateDir))) {
    throw new Error(`模板 ${templateName} 不存在`);
  }
  
  logger.info(`正在复制模板: ${templateName}`);
  
  try {
    // 复制文件
    await fs.copy(templateDir, targetDir);
    
    // 处理模板变量（如果有）
    if (Object.keys(variables).length > 0) {
      await processTemplateVariables(targetDir, variables);
    }
    
    logger.success(`模板复制完成: ${targetDir}`);
  } catch (error) {
    logger.error(`复制模板失败: ${error}`);
    throw error;
  }
};

// 处理模板变量替换
const processTemplateVariables = async (
  dir: string, 
  variables: Record<string, any>
): Promise<void> => {
  const files = await fs.readdir(dir);
  
  for (const file of files) {
    const filePath = path.join(dir, file);
    const stat = await fs.stat(filePath);
    
    if (stat.isDirectory()) {
      await processTemplateVariables(filePath, variables);
    } else if (stat.isFile()) {
      await processFileVariables(filePath, variables);
    }
  }
};

// 处理文件中的变量
const processFileVariables = async (
  filePath: string, 
  variables: Record<string, any>
): Promise<void> => {
  // 只处理文本文件
  const textExtensions = ['.json', '.js', '.ts', '.jsx', '.tsx', '.vue', '.html', '.css', '.md', '.txt'];
  const ext = path.extname(filePath).toLowerCase();
  
  if (!textExtensions.includes(ext)) {
    return;
  }
  
  try {
    let content = await fs.readFile(filePath, 'utf8');
    
    // 简单的变量替换：{{variableName}}
    for (const [key, value] of Object.entries(variables)) {
      const regex = new RegExp(`{{${key}}}`, 'g');
      content = content.replace(regex, String(value));
    }
    
    await fs.writeFile(filePath, content, 'utf8');
  } catch (error) {
    logger.warning(`处理文件变量失败 ${filePath}:`, error);
  }
};